define(['./FormPlugin', ], function(FormPlugin) {
	'use strict';	

	function ActionJScript(options){
		var fnAFRange_ValidateElm = null;

		var AFDigitsRegExp = new RegExp();
		AFDigitsRegExp.compile("\\d+");

		function _runPDFJS(jsString, element, srcValue) {
			try {						
				window.event = window.event || {};		
				if (element){
					window.event.element = element;
				}	
				if (srcValue){
					window.event.value = srcValue;
				}					
				eval(jsString);					
				return window.event;	
			} catch (e) {				
				console.log(e);
				return {value: srcValue, rc: true};			
			}
		}

		function jsEncode(s) {
			//s = s.replace(/\\/g, "\\\\");
			s = s.replace(/\n/g, "\\n");
			//s = s.replace(/\"/g, "\\\"");
			//s = s.replace(/\'/g, "\\\'");
			return s;
		}		

		//返回字串类型
		function getFieldValue(cFields) {
			return options.getItemValue(cFields);
		}		

		function getField(cFields) {
			return {
				value: options.getItemValue(cFields)
			};
		}

		function getFieldNumber(cFields) {
			var num = getFieldValue(cFields);
			return num;
		}

		function getDigits(fNum) {
			var str = fNum.toString();
			var reStr = str.split(".", 2);
			if (reStr === null || reStr.length < 2) {
				reStr = null;
				return 0;
			}

			return reStr[1].length;
		}

		function AFExtractNums(string) {
			/* returns an array of numbers that it managed to extract from the given 
			 * string or null on failure */
			var nums = [];

			if (string.charAt(0) == '.' || string.charAt(0) == ',')
				string = "0" + string;

			while (AFDigitsRegExp.test(string)) {
				nums.length++;
				nums[nums.length - 1] = RegExp.lastMatch;
				string = RegExp.rightContext;
			}
			if (nums.length >= 1) return nums;
			return null;
		}

		function AFMakeNumber(string) {
			/* attempts to make a number out of a string that may not use '.' as the
			 * seperator; it expects that the number is fairly well-behaved other than
			 * possibly having a non-JavaScript friendly separator */
			var type = typeof string;

			if (type == "number")
				return string;
			if (type != "string")
				return null;

			var array = AFExtractNums(string);

			if (array) {
				var joined = array.join(".");

				if (string.indexOf("-.") >= 0)
					joined = "0." + joined;
				var value = joined * (string.indexOf("-") >= 0 ? -1.0 : 1.0);
				return value;
			} else
				return null;
		}

		function AFSimple_Calculat(cFunction, cFields) {
			AFSimple_Calculate(cFunction, cFields);
		}

		function AFSimple_Calculate(cFunction, cFields) {
			var nValue = "";
			var maxDigits = 0;
			var temp = 0;
			var sum = 0;
			var i = 0;
			switch (cFunction) {
				case "AVG":
					{						
						for (i = 0; i < cFields.length; i++) {
							var value = parseFloat(getFieldValue(cFields[i]));
							if (isNaN(value))
								continue;
							temp = getDigits(value);
							maxDigits = maxDigits > temp ? maxDigits : temp;
							sum += value;
						}
						nValue = (sum / cFields.length);
					}
					break;
				case "SUM":
					{
						
						for (i = 0; i < cFields.length; i++) {
							var value = parseFloat(getFieldValue(cFields[i]));
							if (isNaN(value))
								continue;
							temp = getDigits(value);
							maxDigits = maxDigits > temp ? maxDigits : temp;
							sum += value;
						}
						nValue = sum;
					}
					break;
				case "PRD":
					{
						var prd = NaN;
						for (i = 0; i < cFields.length; i++) {
							var value = parseFloat(getFieldValue(cFields[i]));
							if (isNaN(value))
								continue;
							temp = getDigits(value);
							maxDigits = maxDigits > temp ? maxDigits : temp;
							if (isNaN(prd))
								prd = 1;

							prd *= value;
						}
						nValue = isNaN(prd) ? "" : prd;
					}
					break;
				case "MIN":
					{
						var min = NaN;
						for (i = 0; i < cFields.length; i++) {
							var value = parseFloat(getFieldValue(cFields[i]));
							if (isNaN(value))
								continue;
							temp = getDigits(value);
							maxDigits = maxDigits > temp ? maxDigits : temp;
							if (isNaN(min)) {
								min = value;
							}
							if (min > value)
								min = value;
						}

						nValue = isNaN(min) ? "" : min;

					}
					break;
				case "MAX":
					{
						var max = NaN;
						for (var i = 0; i < cFields.length; i++) {
							var value = parseFloat(getFieldValue(cFields[i]));
							if (isNaN(value))
								continue;
							var temp = getDigits(value);
							maxDigits = maxDigits > temp ? maxDigits : temp;
							if (isNaN(max)) {
								max = value;
							}
							if (max < value)
								max = value;
						}
						nValue = isNaN(max) ? "" : max;
					}
					break;
			}		
				
			event.value = nValue;
		}
	

		function AFRange_Validate(bGreaterThan, nGreaterThan, bLessThan, nLessThan) {			
			var cErr = "";			

			if (event.value == "") return;
			
			var value = parseFloat(event.value);
			if (isNaN(value)) {				
				return;
			} else {
				if (bGreaterThan && bLessThan) {
					if (value < nGreaterThan || value > nLessThan)
						cErr = i18n.t("Form.IDS_FX_GTET") + nGreaterThan + i18n.t("Form.IDS_FX_AND_LTET") + nLessThan + ".";
				} else if (bGreaterThan) {
					if (value < nGreaterThan)
						cErr = i18n.t("Form.IDS_FX_GTET") + nGreaterThan + ".";
				} else if (bLessThan) {
					if (value > nLessThan)
						cErr = i18n.t("Form.IDS_FX_AND_LTET") + nLessThan + ".";
				}
			}
			if (cErr !== "") {
				options.alert(null, cErr);								
				event.rc = false;
			}
			
		}

		function FXFormatNumber(nDValue, nfValue, sepStyle, nDec) {
			var sep1 = ".";
			var sep2 = ",";
			var ret = "";
			switch (sepStyle) {
				case 0:
					{}
					break;
				case 1:
					{
						sep2 = "";
					}
					break;
				case 2:
					{
						sep1 = ",";
						sep2 = ".";
					}
					break;
				case 3:
					{
						sep1 = ",";
						sep2 = "";
					}
					break;
			}

			var i = nDValue.length % 3;
			ret = nDValue.substr(0, i);
			for (var j = i; j < nDValue.length; j += 3) {
				if (ret.length !== 0)
					ret += sep2;
				ret += nDValue.substr(j, 3);
			}

			if (nDec > 0) {
				nfValue = nfValue.substring(0, nDec);
				while (nfValue.length < nDec) {
					nfValue += "0";
				}
				ret = ret + sep1 + nfValue;
			}
			return ret;
		}

		function AFNumber_Format(nDec, sepStyle, negStyle, currStyle, strCurrency,
			bCurrencyPrepend) {						
			var value = AFMakeNumber(event.value);
			var sign = (value < 0 ? -1 : 1);
			var fnElm = event.element;	
			 
			var sign = value < 0 ? -1 : 1;
			
			var formatStr = "";
			if ((negStyle == 2 || negStyle == 3) && sign < 0)
				formatStr = "(";
			else
				formatStr = "";

			if (bCurrencyPrepend)
				formatStr = formatStr + strCurrency;
			value = value * sign;
			var subStrArray = value.toString().split(".", 2);
			var nDValue = subStrArray[0];
			var nFValue = "";
			if (subStrArray.length > 1)
				nFValue = subStrArray[1];
			formatStr = formatStr + FXFormatNumber(nDValue, nFValue, sepStyle, nDec);
			if (!bCurrencyPrepend)
				formatStr = formatStr + strCurrency;
			if ((negStyle == 2 || negStyle == 3) && sign < 0)
				formatStr = formatStr + ")";

			if (negStyle !== 0 || bCurrencyPrepend)
				value = Math.abs(value);

			if (negStyle == 1 || negStyle == 3) {
				if (sign > 0)
					fnElm.css("color", "0x000");
				else
					fnElm.css("color", "0xF00");
			}
			if (sign < 0 && bCurrencyPrepend && negStyle == 0)
				formatStr = '-' + formatStr;
			
			event.value = formatStr;
		}

		function AFPercent_Format(nDec, sepStyle) {		
			var value = AFMakeNumber(event.value) * 100;				
			var subStrArray = value.toString().split(".", 2);
			var nDValue = subStrArray[0];
			var nFValue = "0";
			if (subStrArray.length > 1)
				nFValue = subStrArray[1];
			formatStr = FXFormatNumber(nDValue, nFValue, sepStyle, nDec) + "%";
			event.value = formatStr;
		}

		function FXFormatDate(cFormat, date) {

			cFormat = cFormat.replace(/%/g, "%69");
			var mapArray = new Array();
			var tstr = date.getFullYear().toString();
			tstr = "0000" + tstr;
			cFormat = cFormat.replace(/([^y])y{4}(?!y)|(^)y{4}(?!y)/g, "$1" + tstr.substr(tstr.length - 4, 4));

			cFormat = cFormat.replace(/([^y])y{2}(?!y)|(^)y{2}(?!y)/g, "$1" + tstr.substr(tstr.length - 2, 2));

			tstr = AFGetMonthString(date.getMonth() + 1);
			mapArray["%mmmm"] = tstr;
			cFormat = cFormat.replace(/([^m])m{4}(?!m)|(^)m{4}(?!m)/g, "$1%mmmm");

			mapArray["%mmm"] = tstr.substr(0, 3);
			cFormat = cFormat.replace(/([^m])m{3}(?!m)|(^)m{3}(?!m)/g, "$1%mmm");

			cFormat = cFormat.replace(/([^m])m{1}(?!m)|(^)m{1}(?!m)/g, "$1" + (date.getMonth() + 1));

			tstr = (date.getMonth() + 1).toString();
			if (tstr.length == 1)
				tstr = "0" + tstr;
			cFormat = cFormat.replace(/([^m])m{2}(?!m)|(^)m{2}(?!m)/g, "$1" + tstr);

			tstr = AFGetDayString(date.getDay());
			mapArray["%dddd"] = tstr;
			cFormat = cFormat.replace(/([^d])d{4}(?!d)|(^)d{4}(?!d)/g, "$1%dddd");

			mapArray["%ddd"] = tstr.substr(0, 3);
			cFormat = cFormat.replace(/([^d])d{3}(?!d)|(^)d{3}(?!d)/g, "$1%ddd");

			cFormat = cFormat.replace(/([^d])d{1}(?!d)|(^)d{1}(?!d)/g, "$1" + date.getDate());

			tstr = (date.getDate()).toString();
			if (tstr.length == 1)
				tstr = "0" + tstr;
			cFormat = cFormat.replace(/([^d])d{2}(?!d)|(^)d{2}(?!d)/g, "$1" + tstr);

			cFormat = cFormat.replace(/([^H])H{1}(?!H)|(^)H{1}(?!H)/g, "$1" + date.getHours());

			tstr = (date.getHours()).toString();
			if (tstr.length == 1)
				tstr = "0" + tstr;
			cFormat = cFormat.replace(/([^H])H{2}(?!H)|(^)H{2}(?!H)/g, "$1" + tstr);

			cFormat = cFormat.replace(/([^h])h{1}(?!h)|(^)h{1}(?!h)/g, "$1" + (date.getHours() > 12 ? date.getHours() - 12 : date
				.getHours()));
			tstr = ((date.getHours() > 12 ? date.getHours() - 12 : date.getHours()))
				.toString();
			if (tstr.length == 1)
				tstr = "0" + tstr;
			cFormat = cFormat.replace(/([^h])h{2}(?!h)|(^)h{2}(?!h)/g, "$1" + tstr);

			cFormat = cFormat.replace(/([^M])M{1}(?!M)|(^)M{1}(?!M)/g, "$1" + date.getMinutes());

			tstr = (date.getMinutes()).toString();
			if (tstr.length == 1)
				tstr = "0" + tstr;
			cFormat = cFormat.replace(/([^M])M{2}(?!M)|(^)M{2}(?!M)/g, "$1" + tstr);

			cFormat = cFormat.replace(/([^s])s{1}(?!s)|(^)s{1}(?!s)/g, "$1" + date.getSeconds());

			tstr = (date.getSeconds()).toString();
			if (tstr.length == 1)
				tstr = "0" + tstr;
			cFormat = cFormat.replace(/([^s])s{2}(?!s)|(^)s{2}(?!s)/g, "$1" + tstr);

			tstr = AFGetMeridianString(date.getHours());
			cFormat = cFormat.replace(/([^t])t{2}(?!t)|(^)t{2}(?!t)/g, "$1" + tstr);

			if (tstr.length == 1)
				tstr = tstr.charAt(0);
			cFormat = cFormat.replace(/([^t])t{1}(?!t)|(^)t{1}(?!t)/g, "$1" + tstr);

			cFormat = cFormat.replace(/%mmmm/g, mapArray["%mmmm"]);
			cFormat = cFormat.replace(/%mmm/g, mapArray["%mmm"]);
			cFormat = cFormat.replace(/%dddd/g, mapArray["%dddd"]);
			cFormat = cFormat.replace(/%ddd/g, mapArray["%ddd"]);
			cFormat = cFormat.replace(/%69/g, "%");
			mapArray = null;
			return cFormat;
		}

		function AFDate_Format(pdf) {			
			var value = event.value;			
			var cFormat = new Array("m/d", "m/d/yy", "mm/dd/yy", "mm/yy", "d-mmm",
				"d-mmm-yy", "dd-mmm-yy", "yy-mm-dd", "mmm-yy", "mmmm-yy",
				"mmm d, yyyy", "mmmm d, yyyy", "m/d/yy h:MM tt", "m/d/yy HH:MM");
			var date = AFParseDateEx(value, cFormat[pdf]);
			if (!date) {
				options.alert(i18n.t("Form.IDS_FX_DF") + cFormat[pdf].toString());				
				return;
			}
			event.value = FXFormatDate(cFormat[pdf], date);
		}

		function AFDate_FormatEx(cFormat) {			
			var value = event.value;
			if (!value)
				return;

			var dateTime = AFParseDateEx(value, cFormat);
			if (!dateTime) {
				//$("#fwrAlertDialogCloseBtn").focus();
				options.alert(null, i18n.t("Form.IDS_FX_DF") + cFormat);				
				return;
			}
			//Modify by veikin at 2015-2-27 确保前端显示的日期与保存到pdf中的日期一致
			event.value = FXFormatDate(cFormat, dateTime);
			//fnElm.setFieldValue(FXFormatDate(cFormat, dateTime),true);
			//end here
		}

		function AFTime_Format(ptf) {
			var cFormat = new Array("HH:MM", "h:MM tt", "HH:MM:ss", "h:MM:ss tt");
			AFTime_FormatEx(cFormat[ptf]);
		}

		function AFTime_FormatEx(cFormat) {			
			var value = fnElm.val();
			if (!value)
				return;
			var dateTime = AFParseDateEx(value, cFormat);
			if (!dateTime) {
				options.alert(WebPDF.g_pFormPlugin.getReaderApp(), null, i18n.t("Form.IDS_FX_TF") + cFormat);				
				return;
			}

			//Modify by veikin at 2015-2-27 确保前端显示的日期与保存到pdf中的日期一致
			event.value = FXFormatDate(cFormat, dateTime);
			//fnElm.setFieldValue(FXFormatDate(cFormat, dateTime),true);
			//end here
		}

		function AFParseDateEx(value, sFormat) {
			return MakeRegularDate(value, sFormat);

		}

		var IDS_MONTH_INFO = "January[1]February[2]March[3]April[4]May[5]June[6]July[7]August[8]September[9]October[10]Movember[11]December[12]Jan[1]Feb[2]Mar[3]Apr[4]Jun[6]Jul[7]Aug[8]Sep[9]Oct[10]Mov[11]Dec[12]";
		var IDS_DAY_INFO = "Sunday[0]Monday[1]Tuesday[2]Wednesday[3]Thursday[4]Friday[5]Saturday[6]";

		function AFGetMonthString(index) {

			var mthre = new RegExp("(\\w+)\\[" + index + "\\]");
			var result = mthre.exec(IDS_MONTH_INFO);

			if (result)
				return result[1];
			return null;

		}

		function AFGetDayString(index) {

			var dayre = new RegExp("(\\w+)\\[" + index + "\\]");
			var result = dayre.exec(IDS_DAY_INFO);

			if (result)
				return result[1];
			return null;

		}

		function AFGetMeridianString(hour) {

			if (hour > 11)
				return "PM";
			else
				return "AM";

		}

		function MakeRegularDate(value, sFormat) {
			var dRet = ParseFormatDate(value, sFormat);
			if (dRet == null) {
				dRet = ParseNormalDate(value);
			}
			return dRet;
		}

		function ParseFormatDate(value, sFormat) {
			var dt = new Date();

			var nYear = dt.getFullYear();
			var nMonth = dt.getMonth() + 1;
			var nDay = dt.getDate();
			var nHour = dt.getHours();
			var nMin = dt.getMinutes();
			var nSec = dt.getSeconds();

			var nYearSub = 99; //nYear - 2000;

			var bPm = false;
			var bExit = false;
			var bWrongFormat = false;

			var i = 0;
			var j = 0;

			while (i < sFormat.length) {
				if (bExit)
					break;

				var c = sFormat.charAt(i);
				switch (c) {

					case 'y':
					case 'm':
					case 'd':
					case 'H':
					case 'h':
					case 'M':
					case 's':
					case 't':
						{
							var oldj = j;
							var nSkip = 0;
							var retArray = null;
							if (sFormat.charAt(i + 1) != c) {
								switch (c) {
									case 'y':
										i++;
										j++;
										break;
									case 'm':

										retArray = ParseStringInteger(value, j, 2);
										nMonth = retArray.nRet;
										nSkip = retArray.nSkip;
										i++;
										j += nSkip;
										break;
									case 'd':
										retArray = ParseStringInteger(value, j, 2);
										nDay = retArray.nRet;
										nSkip = retArray.nSkip;
										i++;
										j += nSkip;
										break;
									case 'H':
										retArray = ParseStringInteger(value, j, 2);
										nHour = retArray.nRet;
										nSkip = retArray.nSkip;
										i++;
										j += nSkip;
										break;
									case 'h':
										retArray = ParseStringInteger(value, j, 2);
										nHour = retArray.nRet;
										nSkip = retArray.nSkip;
										i++;
										j += nSkip;
										break;
									case 'M':
										retArray = ParseStringInteger(value, j, 2);
										nMin = retArray.nRet;
										nSkip = retArray.nSkip;
										i++;
										j += nSkip;
										break;
									case 's':
										retArray = ParseStringInteger(value, j, 2);
										nSec = retArray.nRet;
										nSkip = retArray.nSkip;
										i++;
										j += nSkip;
										break;
									case 't':

										bPm = value.charAt(i) == 'p';
										i++;
										j++;
										break;
								}
							} else if (sFormat.charAt(i + 1) == c && sFormat.charAt(i + 2) != c) {
								switch (c) {
									case 'y':
										retArray = ParseStringInteger(value, j, 4);
										nYear = retArray.nRet;
										nSkip = retArray.nSkip;
										i += 2;
										j += nSkip;
										break;
									case 'm':
										retArray = ParseStringInteger(value, j, 2);
										nMonth = retArray.nRet;
										nSkip = retArray.nSkip;
										i += 2;
										j += nSkip;
										break;
									case 'd':
										retArray = ParseStringInteger(value, j, 2);
										nDay = retArray["nRet"];
										nSkip = retArray.nSkip;

										i += 2;
										j += nSkip;
										break;
									case 'H':
										retArray = ParseStringInteger(value, j, 2);
										nHour = retArray.nRet;
										nSkip = retArray.nSkip;

										i += 2;
										j += nSkip;
										break;
									case 'h':
										retArray = ParseStringInteger(value, j, 2);
										nHour = retArray.nRet;
										nSkip = retArray.nSkip;

										i += 2;
										j += nSkip;
										break;
									case 'M':
										retArray = ParseStringInteger(value, j, 2);
										nMin = retArray.nRet;
										nSkip = retArray.nSkip;

										i += 2;
										j += nSkip;
										break;
									case 's':
										retArray = ParseStringInteger(value, j, 2);
										nSec = retArray.nRet;
										nSkip = retArray.nSkip;

										i += 2;
										j += nSkip;
										break;
									case 't':
										bPm = (value.charAt(j) == 'p' && value.charAt(j + 1) == 'm');
										i += 2;
										j += 2;
										break;
								}
							} else if (sFormat.charAt(i + 1) == c && sFormat.charAt(i + 2) == c && sFormat.charAt(i + 3) != c) {
								switch (c) {
									case 'm':
										{
											retArray = ParseStringString(value, j);

											nSkip = retArray.nSkip;

											var sMonth = retArray["swRet"];
											var bFind = false;
											for (var m = 0; m < 12; m++) {

												if (sMonth.toLowerCase() == AFGetMonthString(m + 1)
													.substr(0, 3).toLowerCase()) {
													nMonth = m + 1;
													i += 3;
													j += nSkip;
													bFind = true;
													break;
												}
											}

											if (!bFind) {
												retArray = ParseStringInteger(value, j, 3);
												nMonth = retArray["nRet"];
												nSkip = retArray["nSkip"];
												i += 3;
												j += nSkip;
											}
										}
										break;
									case 'y':
										break;
									default:
										i += 3;
										j += 3;
										break;
								}
							} else if (sFormat.charAt(i + 1) == c && sFormat.charAt(i + 2) == c && sFormat.charAt(i + 3) == c && sFormat.charAt(i + 4) != c) {
								switch (c) {
									case 'y':
										retArray = ParseStringInteger(value, j, 4);
										nYear = retArray["nRet"];
										nSkip = retArray["nSkip"];

										j += nSkip;
										i += 4;
										break;
									case 'm':
										{
											var bFind = false;
											retArray = ParseStringString(value, j);

											nSkip = retArray["nSkip"];

											var sMonth = retArray["swRet"];

											sMonth = sMonth.toLowerCase();

											for (var m = 0; m < 12; m++) {
												var sFullMonths = AFGetMonthString(m + 1);
												sFullMonths = sFullMonths.toLowerCase();

												if (sFullMonths.indexOf(sMonth, 0) >= 0) {
													nMonth = m + 1;
													i += 4;
													j += nSkip;
													bFind = true;
													break;
												}
											}

											if (!bFind) {
												retArray = ParseStringInteger(value, j, 4);
												nMonth = retArray["nRet"];
												nSkip = retArray["nSkip"];
												i += 4;
												j += nSkip;
											}
										}
										break;
									default:
										i += 4;
										j += 4;
										break;
								}
							} else {
								if (sFormat.charAt(i) != value.charAt(j)) {
									bWrongFormat = true;
									bExit = true;
								}
								i++;
								j++;
							}

							if (oldj == j) {
								bWrongFormat = true;
								bExit = true;
							}
						}
						break;
					default:
						if (value.length <= j) {
							bExit = true;
						} else if (sFormat.charAt(i) != value.charAt(j)) {
							bWrongFormat = true;
							bExit = true;
						}

						i++;
						j++;
						break;
				}
			}

			if (bPm)
				nHour += 12;

			if (nYear >= 0 && nYear <= nYearSub)
				nYear += 2000;

			if (nMonth < 1 || nMonth > 12)
				bWrongFormat = true;

			if (nDay < 1 || nDay > 31)
				bWrongFormat = true;

			if (nHour < 0 || nHour > 24)
				bWrongFormat = true;

			if (nMin < 0 || nMin > 60)
				bWrongFormat = true;

			if (nSec < 0 || nSec > 60)
				bWrongFormat = true;

			if (!bWrongFormat) {
				return new Date(nYear, nMonth - 1, nDay, nHour, nMin, nSec);
			}

			return null;
		}

		function IsDigit(ch) {
			return (ch >= '0' && ch <= '9');
		}

		function ParseStringInteger(string, nStart, nMaxStep) {

			var rObj = new Array();
			rObj["nRet"] = 0;
			rObj["nSkip"] = 0;

			for (var i = nStart, sz = string.length; i < sz; i++) {
				if (i - nStart > 10)
					break;

				var c = string.charAt(i);
				if (IsDigit(c)) {
					rObj["nRet"] = rObj["nRet"] * 10 + (c - '0');
					rObj["nSkip"] = i - nStart + 1;
					if (rObj["nSkip"] >= nMaxStep)
						break;
				} else
					break;
			}

			return rObj;
		}

		function ParseStringString(string, nStart) {

			var rObj = new Array();
			rObj["swRet"] = null;
			rObj["nSkip"] = 0;

			for (var i = nStart, sz = string.length; i < sz; i++) {
				var c = string.charAt(i);
				if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z')) {
					rObj["swRet"] += c;
					rObj["nSkip"] = i - nStart + 1;
				} else
					break;
			}

			return rObj;
		}

		function GuessDate(nCount, n1, n2, n3, nYear, nMonth, nDay) {
			var retObj = new Array();
			retObj["y"] = nYear;
			retObj["m"] = nMonth;
			retObj["d"] = nDay;

			if (nCount == 2) {
				// case2: month/day
				// case3: day/month
				if ((n1 >= 1 && n1 <= 12) && (n2 >= 1 && n2 <= 31)) {

					retObj["m"] = n1;
					retObj["d"] = n2;

					return retObj;
				} else if ((n1 >= 1 && n1 <= 31) && (n2 >= 1 && n2 <= 12)) {

					retObj["m"] = n2;
					retObj["d"] = n1;
					return retObj;
				}
			} else if (nCount >= 3) {
				// case1: year/month/day
				// case2: month/day/year
				// case3: day/month/year
				if (n1 > 12 && (n2 >= 1 && n2 <= 12) && (n3 >= 1 && n3 <= 31)) {
					retObj["y"] = n1;
					retObj["m"] = n2;
					retObj["d"] = n3;

					return retObj;
				} else if ((n1 >= 1 && n1 <= 12) && (n2 >= 1 && n2 <= 31) && n3 > 31) {
					retObj["y"] = n3;
					retObj["m"] = n1;
					retObj["d"] = n2;

					return retObj;
				} else if ((n1 >= 1 && n1 <= 31) && (n2 >= 1 && n2 <= 12) && n3 > 31) {
					retObj["y"] = n3;
					retObj["m"] = n2;
					retObj["d"] = n1;

					return retObj;
				}
			}

			return null;
		}

		function GuessTime(nCount, n1, n2, n3, nHour, nMin, nSec) {
			var retObj = new Array();
			retObj["h"] = nHour;
			retObj["M"] = nMin;
			retObj["s"] = nSec;
			if (nCount == 2) {
				//hh:mm
				if ((n1 >= 0 && n1 <= 23) && (n2 >= 0 && n2 <= 59)) {
					retObj["h"] = n1;
					retObj["M"] = n2;
					retObj["s"] = 0;

					return retObj;
				}
			} else if (nCount == 3) {
				//hh:mm:ss
				if ((n1 >= 0 && n1 <= 23) && (n2 >= 0 && n2 <= 59) && (n3 >= 0 && n3 <= 59)) {
					retObj["h"] = n1;
					retObj["M"] = n2;
					retObj["s"] = n3;

					return retObj;
				}
			}

			return null;
		}

		function ParseNormalDate(value) {
			var dt = new Date();

			var nYear = dt.getFullYear();
			var nMonth = dt.getMonth() + 1;
			var nDay = dt.getDate();
			var nHour = dt.getHours();
			var nMin = dt.getMinutes();
			var nSec = dt.getSeconds();

			var number = new Array();
			for (var j = 0; j < 6; j++)
				number[j] = 0;

			var bTime = false;

			var nCount = 0;
			var i = 0;
			var nLen = value.length;
			while (i < nLen) {
				if (nCount > 5)
					break;

				var c = value.charAt(i);
				if (IsDigit(c)) {
					var nSkip = 0;
					var retObj = ParseStringInteger(value, i, 4);
					number[nCount++] = retObj["nRet"];
					nSkip = retObj["nSkip"];
					i += nSkip;
				} else {
					if (c == ':')
						bTime = true;

					i++;
				}
			}

			var bWrongFormat = true;

			if (bTime) {
				if (nCount <= 3) {
					var timeObj = GuessTime(nCount, number[0], number[1],
						number[2], nHour, nMin, nSec);

					if (timeObj) {
						nHour = timeObj["h"];
						nMin = timeObj["M"];
						nSec = timeObj["s"];

						bWrongFormat = false;
					}
				} else if (nCount == 4) {
					var timeObj = GuessDate(2, number[0], number[1], 0, nYear,
						nMonth, nDay);

					if (timeObj) {
						nYear = timeObj["y"];
						nMonth = timeObj["m"];
						nDay = timeObj["d"];
						timeObj = GuessTime(2, number[2], number[3], 0, nHour,
							nMin, nSec);
						if (timeObj) {
							nHour = timeObj["h"];
							nMin = timeObj["M"];
							nSec = timeObj["s"];
							bWrongFormat = false;
						}
					}
				} else if (nCount == 5) {
					var timeObj = GuessDate(3, number[0], number[1], number[2],
						nYear, nMonth, nDay);

					if (timeObj) {
						nYear = timeObj["y"];
						nMonth = timeObj["m"];
						nDay = timeObj["d"];
						timeObj = GuessTime(2, number[3], number[4], 0, nHour,
							nMin, nSec);

						if (timeObj) {
							nHour = timeObj["h"];
							nMin = timeObj["M"];
							nSec = timeObj["s"];
							bWrongFormat = false;
						}
					}

					if (bWrongFormat) {
						var timeObj = GuessDate(2, number[0], number[1], 0, nYear,
							nMonth, nDay);

						if (timeObj) {
							nYear = timeObj["y"];
							nMonth = timeObj["m"];
							nDay = timeObj["d"];
							timeObj = GuessTime(3, number[2], number[3], number[4],
								nHour, nMin, nSec);

							if (timeObj) {
								nHour = timeObj["h"];
								nMin = timeObj["M"];
								nSec = timeObj["s"];
								bWrongFormat = false;
							}
						}
					}
				} else if (nCount == 6) {
					var timeObj = GuessDate(3, number[0], number[1], number[2],
						nYear, nMonth, nDay);

					if (timeObj) {
						nYear = timeObj["y"];
						nMonth = timeObj["m"];
						nDay = timeObj["d"];
						timeObj = GuessTime(3, number[3], number[4], number[5],
							nHour, nMin, nSec);
						if (timeObj) {
							nHour = timeObj["h"];
							nMin = timeObj["M"];
							nSec = timeObj["s"];
							bWrongFormat = false;
						}
					}
				}
			}

			if (bWrongFormat) {
				var timeObj = GuessDate(nCount, number[0], number[1], number[2],
					nYear, nMonth, nDay);

				if (timeObj) {
					nYear = timeObj["y"];
					nMonth = timeObj["m"];
					nDay = timeObj["d"];
					bWrongFormat = (nCount > 3);
				}
			}

			if (bWrongFormat)
				return null;

			return new Date(nYear, nMonth - 1, nDay, nHour, nMin, nSec);
		}				

		return _runPDFJS;
	}

	return {
		init: function(options){
			return new ActionJScript(options);
		}
	};
});